package com.logos.cartoon.utils;

import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTValidator;
import cn.hutool.jwt.signers.JWTSigner;
import cn.hutool.jwt.signers.JWTSignerUtil;
import com.logos.cartoon.exception.UnauthorizedException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.security.Key;
import java.time.Duration;
import java.util.Date;

@Component
@ConditionalOnProperty(prefix = "cartoon.jwt", name = "enabled", havingValue = "true")
public class JwtTool {

    @Value("${cartoon.jwt.key}")
    private String key;

    private JWTSigner jwtSigner;
    @PostConstruct
    public void init() {
        if (key == null || key.isEmpty()) {
            throw new IllegalArgumentException("JWT密钥不能为空，请检查配置文件");
        }
        this.jwtSigner = JWTSignerUtil.createSigner("HS256", key.getBytes());
    }

    /**
     * 创建 access-token
     *
     * @param phone 用户手机号
     * @param ttl   token有效期
     * @return access-token
     */
    public String createToken(String phone, Duration ttl) {
        return JWT.create()
                .setPayload("user-phone", phone)
                .setExpiresAt(new Date(System.currentTimeMillis() + ttl.toMillis()))
                .setSigner(jwtSigner)
                .sign();
    }

    /**
     * 解析token
     *
     * @param token token字符串
     * @return 解析刷新token得到的用户信息
     */
    public String parseToken(String token) {
        if (token == null || token.isEmpty()) {
            throw new UnauthorizedException("未登录");
        }

        try {
            JWT jwt = JWT.of(token).setSigner(jwtSigner);

            if (!jwt.verify()) {
                throw new UnauthorizedException("无效的token");
            }
            JWTValidator.of(jwt).validateDate();

            Object userPayload = jwt.getPayload("user-phone");
            if (userPayload == null) {
                throw new UnauthorizedException("无效的token");
            }
            return userPayload.toString();
        } catch (ValidateException e) {
            throw new UnauthorizedException("token已经过期");
        } catch (RuntimeException e) {
            throw new UnauthorizedException("无效的token");
        }
    }
};